from lexer import Token, TT_KEYWORD, TT_IDENTIFIER, TT_CONST, TT_OPERATOR, TT_DELIMITER, TT_EOF, Error

class ParseResult:
    def __init__(self):
        self.error = None
        self.node = None
        
    def register(self, res):
        if isinstance(res, ParseResult):
            if res.error: 
                self.error = res.error
            return res.node
        return res

    def success(self, node):
        self.node = node
        return self

    def failure(self, error):
        self.error = error
        return self

class Node:
    pass

class SelectNode(Node):
    def __init__(self, fields, table, where_condition=None):
        self.fields = fields
        self.table = table
        self.where_condition = where_condition
    def __repr__(self):
        return f"SelectNode(fields={self.fields}, table={self.table}, where_condition={self.where_condition})"

class CreateTableNode(Node):
    def __init__(self, table_name, columns):
        self.table_name = table_name
        self.columns = columns
    def __repr__(self):
        return f"CreateTableNode(table_name={self.table_name}, columns={self.columns})"

class InsertNode(Node):
    def __init__(self, table_name, values):
        self.table_name = table_name
        self.values = values
    def __repr__(self):
        return f"InsertNode(table_name={self.table_name}, values={self.values})"

class DeleteNode(Node):
    def __init__(self, table_name, where_condition=None):
        self.table_name = table_name
        self.where_condition = where_condition
    def __repr__(self):
        return f"DeleteNode(table_name={self.table_name}, where_condition={self.where_condition})"

class Parser:
    def __init__(self, tokens):
        self.tokens = tokens
        self.tok_idx = -1
        self.advance()

    def advance(self):
        self.tok_idx += 1
        if self.tok_idx < len(self.tokens):
            self.current_tok = self.tokens[self.tok_idx]
        return self.current_tok

    def parse(self):
        res = ParseResult()
        tok = self.current_tok

        if tok.matches(TT_KEYWORD, 'SELECT'):
            return self.parse_select()
        elif tok.matches(TT_KEYWORD, 'CREATE'):
            return self.parse_create_table()
        elif tok.matches(TT_KEYWORD, 'INSERT'):
            return self.parse_insert()
        elif tok.matches(TT_KEYWORD, 'DELETE'):
            return self.parse_delete()
        else:
            return res.failure(Error(
                tok.pos_start, tok.pos_end,
                "Invalid Syntax",
                f"Expected SELECT, CREATE, INSERT or DELETE, got '{tok.value}'"
            ))

    def parse_select(self):
        res = ParseResult()
        self.advance()  # 跳过SELECT
        
        # 解析字段列表
        fields = []
        while (self.current_tok.type != TT_KEYWORD or self.current_tok.value != 'FROM') and self.current_tok.type != TT_EOF:
            if self.current_tok.type in (TT_IDENTIFIER, TT_OPERATOR) and self.current_tok.value == '*':
                fields.append(self.current_tok)
                self.advance()
            elif self.current_tok.type == TT_IDENTIFIER:
                fields.append(self.current_tok)
                self.advance()
            else:
                break
                
            if self.current_tok.type == TT_DELIMITER and self.current_tok.value == ',':
                self.advance()

        # 检查FROM关键字
        if not (self.current_tok.type == TT_KEYWORD and self.current_tok.value == 'FROM'):
            return res.failure(Error(
                self.current_tok.pos_start, self.current_tok.pos_end,
                "Invalid Syntax",
                "Expected FROM keyword"
            ))
        
        self.advance()  # 跳过FROM
        
        # 解析表名
        if self.current_tok.type != TT_IDENTIFIER:
            return res.failure(Error(
                self.current_tok.pos_start, self.current_tok.pos_end,
                "Invalid Syntax",
                "Expected table name"
            ))
        
        table = self.current_tok
        self.advance()

        # 解析可选的WHERE子句
        condition = None
        if self.current_tok.type == TT_KEYWORD and self.current_tok.value == 'WHERE':
            self.advance()
            condition_result = self.parse_condition()
            if condition_result.error:
                return condition_result
            condition = condition_result.node

        return res.success(SelectNode(fields, table, condition))

    def parse_create_table(self):
        res = ParseResult()
        self.advance()  # 跳过CREATE
        
        # 检查TABLE关键字
        if not (self.current_tok.type == TT_KEYWORD and self.current_tok.value == 'TABLE'):
            return res.failure(Error(
                self.current_tok.pos_start, self.current_tok.pos_end,
                "Invalid Syntax",
                "Expected TABLE keyword"
            ))
        
        self.advance()  # 跳过TABLE

        # 解析表名
        if self.current_tok.type != TT_IDENTIFIER:
            return res.failure(Error(
                self.current_tok.pos_start, self.current_tok.pos_end,
                "Invalid Syntax",
                "Expected table name"
            ))
        
        table_name = self.current_tok
        self.advance()

        # 检查左括号
        if not (self.current_tok.type == TT_DELIMITER and self.current_tok.value == '('):
            return res.failure(Error(
                self.current_tok.pos_start, self.current_tok.pos_end,
                "Invalid Syntax",
                "Expected '(' after table name"
            ))
        
        self.advance()  # 跳过'('

        # 解析列名列表
        columns = []
        while self.current_tok.type != TT_DELIMITER or self.current_tok.value != ')':
            if self.current_tok.type == TT_IDENTIFIER:
                columns.append(self.current_tok)
                self.advance()
                
                # 检查是否有逗号或右括号
                if self.current_tok.type == TT_DELIMITER and self.current_tok.value == ',':
                    self.advance()
                elif self.current_tok.type == TT_DELIMITER and self.current_tok.value == ')':
                    break
                else:
                    return res.failure(Error(
                        self.current_tok.pos_start, self.current_tok.pos_end,
                        "Invalid Syntax",
                        "Expected ',' or ')' after column name"
                    ))
            else:
                return res.failure(Error(
                    self.current_tok.pos_start, self.current_tok.pos_end,
                    "Invalid Syntax",
                    "Expected column name"
                ))

        # 检查右括号
        if not (self.current_tok.type == TT_DELIMITER and self.current_tok.value == ')'):
            return res.failure(Error(
                self.current_tok.pos_start, self.current_tok.pos_end,
                "Invalid Syntax",
                "Expected ')' after column list"
            ))
        
        self.advance()  # 跳过')'

        return res.success(CreateTableNode(table_name, columns))

    def parse_insert(self):
        res = ParseResult()
        self.advance()  # 跳过INSERT
        
        # 检查INTO关键字
        if not (self.current_tok.type == TT_KEYWORD and self.current_tok.value == 'INTO'):
            return res.failure(Error(
                self.current_tok.pos_start, self.current_tok.pos_end,
                "Invalid Syntax",
                "Expected INTO keyword"
            ))
        
        self.advance()  # 跳过INTO

        # 解析表名
        if self.current_tok.type != TT_IDENTIFIER:
            return res.failure(Error(
                self.current_tok.pos_start, self.current_tok.pos_end,
                "Invalid Syntax",
                "Expected table name"
            ))
        
        table_name = self.current_tok
        self.advance()

        # 检查VALUES关键字
        if not (self.current_tok.type == TT_KEYWORD and self.current_tok.value == 'VALUES'):
            return res.failure(Error(
                self.current_tok.pos_start, self.current_tok.pos_end,
                "Invalid Syntax",
                "Expected VALUES keyword"
            ))
        
        self.advance()  # 跳过VALUES

        # 检查左括号
        if not (self.current_tok.type == TT_DELIMITER and self.current_tok.value == '('):
            return res.failure(Error(
                self.current_tok.pos_start, self.current_tok.pos_end,
                "Invalid Syntax",
                "Expected '(' after VALUES"
            ))
        
        self.advance()  # 跳过'('

        # 解析值列表
        values = []
        while self.current_tok.type != TT_DELIMITER or self.current_tok.value != ')':
            if self.current_tok.type in (TT_CONST, TT_IDENTIFIER):
                values.append(self.current_tok)
                self.advance()
                
                # 检查是否有逗号或右括号
                if self.current_tok.type == TT_DELIMITER and self.current_tok.value == ',':
                    self.advance()
                elif self.current_tok.type == TT_DELIMITER and self.current_tok.value == ')':
                    break
                else:
                    return res.failure(Error(
                        self.current_tok.pos_start, self.current_tok.pos_end,
                        "Invalid Syntax",
                        "Expected ',' or ')' after value"
                    ))
            else:
                return res.failure(Error(
                    self.current_tok.pos_start, self.current_tok.pos_end,
                    "Invalid Syntax",
                    "Expected value"
                ))

        # 检查右括号
        if not (self.current_tok.type == TT_DELIMITER and self.current_tok.value == ')'):
            return res.failure(Error(
                self.current_tok.pos_start, self.current_tok.pos_end,
                "Invalid Syntax",
                "Expected ')' after values list"
            ))
        
        self.advance()  # 跳过')'

        return res.success(InsertNode(table_name, values))

    def parse_delete(self):
        res = ParseResult()
        self.advance()  # 跳过DELETE
        
        # 检查FROM关键字
        if not (self.current_tok.type == TT_KEYWORD and self.current_tok.value == 'FROM'):
            return res.failure(Error(
                self.current_tok.pos_start, self.current_tok.pos_end,
                "Invalid Syntax",
                "Expected FROM keyword"
            ))
        
        self.advance()  # 跳过FROM

        # 解析表名
        if self.current_tok.type != TT_IDENTIFIER:
            return res.failure(Error(
                self.current_tok.pos_start, self.current_tok.pos_end,
                "Invalid Syntax",
                "Expected table name"
            ))
        
        table_name = self.current_tok
        self.advance()

        # 解析可选的WHERE子句
        condition = None
        if self.current_tok.type == TT_KEYWORD and self.current_tok.value == 'WHERE':
            self.advance()
            condition_result = self.parse_condition()
            if condition_result.error:
                return condition_result
            condition = condition_result.node

        return res.success(DeleteNode(table_name, condition))

    def parse_condition(self):
        res = ParseResult()
        
        # 解析左操作数
        if self.current_tok.type != TT_IDENTIFIER:
            return res.failure(Error(
                self.current_tok.pos_start, self.current_tok.pos_end,
                "Invalid Syntax",
                "Expected identifier in condition"
            ))
        
        left = self.current_tok
        self.advance()

        # 解析操作符
        if self.current_tok.type != TT_OPERATOR:
            return res.failure(Error(
                self.current_tok.pos_start, self.current_tok.pos_end,
                "Invalid Syntax",
                "Expected operator in condition"
            ))
        
        op = self.current_tok
        self.advance()

        # 解析右操作数
        if self.current_tok.type not in (TT_CONST, TT_IDENTIFIER):
            return res.failure(Error(
                self.current_tok.pos_start, self.current_tok.pos_end,
                "Invalid Syntax",
                "Expected value or identifier in condition"
            ))
        
        right = self.current_tok
        self.advance()

        return res.success((left, op, right))